/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       keyboard.cpp
 * Author:     karooolek
 * Created on: 2009-01-05
 *
 **********************************************************************************************************************/

#include "keyboard.h"

namespace mGameEngine
{
namespace Input
{

uint8 Keyboard::_keys[512];
List<KeyboardListener *> Keyboard::_listeners;

void Keyboard::_glutKeyboardFunc(uint8 key, int, int)
{
    key = tolower(key);

    _keys[key] = 2;

    for(List<KeyboardListener *>::Iterator i = _listeners.begin();
        i != _listeners.end();
        ++i)
    {
        KeyboardListener *l = *i;
        l->keyDown(KeyCode(key));
    }
}

void Keyboard::_glutKeyboardUpFunc(uint8 key, int, int)
{
    key = tolower(key);

    _keys[key] = 0;

    for(List<KeyboardListener *>::Iterator i = _listeners.begin();
        i != _listeners.end();
        ++i)
    {
        KeyboardListener *l = *i;
        l->keyUp(KeyCode(key));
    }
}

void Keyboard::_glutKeyboardSpecialFunc(int key, int, int)
{
    _keys[key + 256] = 2;

    for(List<KeyboardListener *>::Iterator i = _listeners.begin();
        i != _listeners.end();
        ++i)
    {
        KeyboardListener *l = *i;
        l->keyDown(KeyCode(key + 256));
    }
}

void Keyboard::_glutKeyboardSpecialUpFunc(int key, int, int)
{
    _keys[key + 256] = 0;

    for(List<KeyboardListener *>::Iterator i = _listeners.begin();
        i != _listeners.end();
        ++i)
    {
        KeyboardListener *l = *i;
        l->keyUp(KeyCode(key + 256));
    }
}

bool Keyboard::isKeyDown(KeyCode key)
{
    return _keys[key] > 0;
}

KeyCode Keyboard::getAnyKeyDown()
{
    uint key;
    for(key = 511; _keys[key] == 0 && key != KEY_CODE_NONE; --key);
    return KeyCode(key);
}

void Keyboard::addListener(KeyboardListener *listener)
{
    if(!listener)
    {
        return;
    }

    _listeners.push_back(listener);
    _listeners.unique();
}

void Keyboard::removeListener(KeyboardListener *listener)
{
    _listeners.remove(listener);
}

}
}
